/*
 * $Id: SimpleGradientBoxStyle.java 101 2009-04-30 14:06:55Z meyer@alphatec.de $
 * 
 *
 * Copyright 2009 DeltaDesk
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package deltadesk.gui.deltagui.widget.box;

import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.RoundRectangle2D;

import deltadesk.gui.deltagui.geom.Insets;

/**
 * SimpleGradientBoxStyle
 * 
 * Inspired by the panels of DhilshukReddy.
 * 
 * @author Andreas Meyer
 * @version $Revision: 101 $
 */
public class SimpleGradientBoxStyle implements BoxStyle {
	
	/** 
	 * The gradient direction. 
	 */
	public enum Direction {
		
		VERTICAL,
		HORIZONTAL,
		VERTICAL_RAISED,
		HORIZONTAL_RAISED
	}

	/** The start color of the gradient. */
	private final Color startColor = new Color(255,255,255);

	/** The end color of the gradient. */
	private final Color endColor = new Color(82, 82, 82);
	
	/** The outer rectangle size. */
	private final int outerRoundRectSize = 10;
	
	/** The inner rectangle size. */
	private final int innerRoundRectSize = 8;

	/** The direction of the gradient. */
	private Direction direction = Direction.HORIZONTAL_RAISED;


	/**
	 * @see deltadesk.gui.deltagui.graphics.Renderable#render(java.awt.Graphics2D)
	 */
	public void render(final Graphics2D g2) {

		final Rectangle rect = g2.getClipBounds();
		
		final Insets insets = new Insets();
		int vWidth = rect.width - (insets.getLeft() + insets.getRight());
		int vHeight = rect.height - (insets.getTop() + insets.getBottom());

		if (direction == Direction.HORIZONTAL) {
			
			paintHorizontalGradient(g2, insets.getLeft(), insets.getTop(),
					vWidth, vHeight, rect.width);
		} else if (direction == Direction.VERTICAL) {
			
			paintVerticalGradient(g2, insets.getLeft(), insets.getTop(),
					vWidth, vHeight, rect.height);
		} else if (direction == Direction.HORIZONTAL_RAISED) {
			
			paintHorizontalRaisedGradient(g2, insets.getLeft(), insets.getTop(),
					vWidth, vHeight, rect.width);
    	} else if (direction == Direction.VERTICAL_RAISED) {
			
    		paintVerticalRaisedGradient(g2, insets.getLeft(), insets.getTop(),
					vWidth, vHeight, rect.height);
		}

	}

	/**
	 * Paints a vertical gradient background from the start color to the 
	 * end color.
	 * 
	 * @param g2d
	 * @param x
	 * @param y
	 * @param w
	 * @param h
	 * @param height
	 */
	private void paintVerticalGradient(final Graphics2D g2d, final int x, 
			final int y, final int w, final int h, final int height) {

		GradientPaint gp = new GradientPaint(0, 0, startColor, 0, h, endColor, true);
		g2d.setPaint(gp);

		g2d.setPaint(Color.BLACK);
		g2d.drawRoundRect(0, 0, w - 1, h - 1, outerRoundRectSize, outerRoundRectSize);
		g2d.setPaint(gp);
		g2d.fillRoundRect(1, 1, w - 2, h - 2, outerRoundRectSize, outerRoundRectSize);
	}

	/**
	 * Paints a vertical-raised gradient background from the start color to 
	 * the end color.
	 * 
	 * @param g2d
	 * @param x
	 * @param y
	 * @param w
	 * @param h
	 * @param height
	 */
	private void paintVerticalRaisedGradient(final Graphics2D g2d, final int x, 
			final int y, final int w, final int h, final int height) {

		GradientPaint p1;
		GradientPaint p2;
		GradientPaint gp = new GradientPaint(0, 0, startColor, 0, h, endColor, true);
		g2d.setPaint(gp);

		p1 = new GradientPaint(0, 0, new Color(0, 0, 0), 0, h - 1, new Color(
				100, 100, 100));
		p2 = new GradientPaint(0, 1, new Color(0, 0, 0, 50), 0, h - 3,
				new Color(255, 255, 255, 100));
		g2d.setPaint(Color.BLACK);
		g2d.drawRoundRect(0, 0, w - 1, h - 1, outerRoundRectSize,
				outerRoundRectSize);
		g2d.setPaint(gp);
		g2d.fillRoundRect(1, 1, w - 2, h - 2, outerRoundRectSize,
				outerRoundRectSize);

		g2d.setPaint(p1);
		g2d.drawRoundRect(0, 0, w - 1, h - 1, outerRoundRectSize,
				outerRoundRectSize);
		g2d.setPaint(p2);
		g2d.drawRoundRect(1, 1, w - 3, h - 3, innerRoundRectSize,
				innerRoundRectSize);
	}
	
	/**
	 * Paints a horizontal gradient background from the start color to the 
	 * end color.
	 * 
	 * @param g2d
	 * @param x
	 * @param y
	 * @param w
	 * @param h
	 * @param width
	 */
	private void paintHorizontalGradient(final Graphics2D g2d, final int x, 
			final int y, final int w, final int h, final int width) {

		GradientPaint gp = new GradientPaint(0, 0, startColor, w, 0, endColor, true);
		g2d.setPaint(gp);
		g2d.setPaint(Color.BLACK);
		g2d.drawRoundRect(0, 0, w - 1, h - 1, outerRoundRectSize,
				outerRoundRectSize);
		g2d.setPaint(gp);
		g2d.fillRoundRect(1, 1, w - 2, h - 2, outerRoundRectSize,
				outerRoundRectSize);
	}

	/**
	 * Paints a horizontal-raised gradient background from the start color to 
	 * the end color.
	 * 
	 * @param g2d
	 * @param x
	 * @param y
	 * @param w
	 * @param h
	 * @param width
	 */
	private void paintHorizontalRaisedGradient(final Graphics2D g2d, 
			final int x, final int y, final int w, final int h, 
			final int width) {

		GradientPaint p1;
		GradientPaint p2;
		GradientPaint gp = new GradientPaint(0, 0, startColor, w, 0, endColor, true);
		g2d.setPaint(gp);
		p1 = new GradientPaint(0, 0, new Color(0, 0, 0), w - 3, 0, new Color(
				100, 100, 100));
		p2 = new GradientPaint(1, 0, new Color(0, 0, 0, 50), w - 3, 0,
				new Color(255, 255, 255, 100));

		RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(0, 0, w - 1,
				h - 1, outerRoundRectSize, outerRoundRectSize);
		Shape clip = g2d.getClip();
		g2d.clip(r2d);
		g2d.fillRect(0, 0, w, h);
		g2d.setClip(clip);
		g2d.setPaint(p1);

		g2d.setPaint(Color.BLACK);
		g2d.drawRoundRect(0, 0, w - 1, h - 1, outerRoundRectSize,
				outerRoundRectSize);
		g2d.setPaint(p2);
		g2d.fillRoundRect(1, 1, w - 2, h - 2, outerRoundRectSize,
				outerRoundRectSize);

		g2d.setPaint(Color.WHITE);
		g2d.drawRoundRect(1, 1, w - 3, h - 3, outerRoundRectSize,
				outerRoundRectSize);
		g2d.setPaint(p2);
		g2d.drawRoundRect(1, 1, w - 2, h - 2, innerRoundRectSize,
				innerRoundRectSize);
	}

}
